package fr.emse.tatiana.replayable;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;

import fr.emse.tatiana.display.DisplayTable;
import fr.emse.tatiana.display.ReplayableDisplayShower;
import fr.emse.tatiana.replayable.analysis.IAnalysis;

public class ReplayableModelFactory {
	
	public static Map<String,IReplayableModel> reusablemodels = new HashMap<String, IReplayableModel>();
	public static Map<String,Integer> useCount = new HashMap<String, Integer>();
	
	public static IReplayableModel getEditableReplayableModel(IFile file, List<IAnalysis> analyses) {
		String key = file.getFullPath().toString();
		if (reusablemodels.containsKey(key)) {
			return reuseModel(key);
		}
		IReplayableModel ret = new ReplayableModel(file, analyses);
		setModel(key, ret);
		return ret;
	}
	
	public static IReplayableModel getFilteredReplayableModel(String displayfile, String displaylayoutfile, List<IAnalysis> analyses) {
		String key = displayfile;
		if (reusablemodels.containsKey(key)) {
			return reuseModel(key);
		}
		DisplayTable dt = (displaylayoutfile==null) ? 
				new DisplayTable(displayfile):
				new DisplayTable(displaylayoutfile,displayfile);
		IReplayableModel ret = new ReplayableDisplayShower(dt,analyses);
		setModel(key, ret);
		
		return ret;
	}
	
	public static void releaseFilteredModel(String displayfile) {
		String key = displayfile;
		releaseModel(key);
	}
	
	public static void releaseEditableModel(IFile file) {
		try {
			String key= file.getFullPath().toString();
			releaseModel(key);
		} catch (NullPointerException npe) {
			return; // file didn't exist
		}
	}
	
	private static void releaseModel(String key) {
		if (useCount.containsKey(key)) {
			int count = useCount.get(key);
			count--;
			if (count<=0) {
				useCount.remove(key);
				reusablemodels.remove(key);
			}
		}
	}
	
	// only call if we're sure the key is set
	private static IReplayableModel reuseModel(String key) {
		int count = useCount.get(key);
		count++;
		useCount.put(key, count);
		return reusablemodels.get(key);
	}
	
	// only call if we're sure the key is not set
	private static void setModel(String key, IReplayableModel model) {
		useCount.put(key, 1);
		reusablemodels.put(key, model);
	}

	public static void removeFilteredModel(String displayfilepath) {
		useCount.remove(displayfilepath);
		reusablemodels.remove(displayfilepath);
		
	}
	
}
